#ifndef	GENERIC_H
#define	GENERIC_H
#include "rawkeys.h"
#include "rawmouse.h"

#ifdef BROKEN_SPRINTF
# undef	 sprintf
# define sprintf(str, format, args...) snprintf(str, 256, format, ##args)
#endif /* BROKEN_SPRINTF */

#ifdef	__GNUC__
# define __packed __attribute__ ((packed))
#else
# define __packed
#endif

typedef enum {			// 
  FALSE, TRUE
} __packed bool;

struct rgb {			// 
  unsigned char r, g, b;
} __packed;

struct argb {			// 
  unsigned char a;
  struct rgb rgb;
} __packed;

struct DisplayDimension {
  bool changedOffset;		// offset of display-device in global desktop (eg. the window on a screen)
  int X, Y;
  bool changedSize;		// size of display-device in global desktop (eg. the window on a screen)
  int Width, Height;
  bool changedDesktopOffset;	// offset of global desktop (eg. the screen)
  int dtX, dtY;
  bool changedDesktopSize;	// size of global desktop (eg. the screen)
  int dtWidth, dtHeight;
  
  bool changedBuffer;		// the actual used framebuffer
  void *frameBuffer;
  int frameSize;

 /*
  bool changedPalette;
  struct rgb *Palette;
  */
};

extern struct DisplayDimension localDim;

/*
 * here are the structs, externals and functions descripted,
 * that could but must not be implemented by the system-drivers
 * the file generic will ever compiled, you can activate
 * your functions with defines
 */

#undef	OPENDISPLAY
struct DisplayDimension *OpenDisplay(int width, int height, int depth, struct rgb *Palette);
#undef	SWAPDISPLAY
void *SwapDisplay(void *oldBuffer);
#undef	UPDATEDISPLAY
void *UpdateDisplay(void *oldBuffer, int x, int y, int width, int height);
#undef	CHANGEDISPLAY
struct DisplayDimension *ChangeDisplay(int width, int height, int depth, struct rgb *Palette);
#undef	CLOSEDISPLAY
void CloseDisplay(void);

#undef	OPENKEYS
void OpenKeys(void);
#undef	GETKEYS
bool GetKeys(struct keyEvent *eventBuffer);
#undef	CLOSEKEYS
void CloseKeys(void);

#undef	OPENMOUSE
void OpenMouse(void);
#undef	GETMOUSE
void GetMouse(struct mouseEvent *eventBuffer);
#undef	CLOSEMOUSE
void CloseMouse(void);

void SetDisplay(struct DisplayDimension *dim);

/* canonical system */
#include "@target_cpu@/@target_cpu@.h"
#include "@target_cpu@/@target_os@/@target_os@.h"

#ifndef	MATCH
unsigned char Match(register struct rgb *rawpix, register struct rgb *Palette);
#endif

#ifdef INLINE_BIGENDIAN
#ifndef	SWAPSHORT
#define	SWAPSHORT
static short SwapShort(short l);
static inline short SwapShort(short l) {
  unsigned char b1, b2;

  b1 = l & 255;
  b2 = (l >> 8) & 255;

  return (b1 << 8) + b2;
}
#endif

#ifndef	SWAPLONG
#define	SWAPLONG
static int SwapLong(int l);
static inline int SwapLong(int l) {
  unsigned char b1, b2, b3, b4;

  b1 = l & 255;
  b2 = (l >> 8) & 255;
  b3 = (l >> 16) & 255;
  b4 = (l >> 24) & 255;

  return ((int)b1 << 24) + ((int)b2 << 16) + ((int)b3 << 8) + b4;
}
#endif

#ifndef	SWAPFLOAT
#define	SWAPFLOAT
static float SwapFloat(float l);
static inline float SwapFloat(float l) {
  union {
    unsigned char b[4];
    float f;
  } in, out;

  in.f = l;
  out.b[0] = in.b[3];
  out.b[1] = in.b[2];
  out.b[2] = in.b[1];
  out.b[3] = in.b[0];

  return out.f;
}
#endif
#endif

#if (WORDS_BIGENDIAN == 1)
#define BigShort(a) (a)
#define LittleShort(a) SwapShort(a)
#define BigLong(a) (a)
#define LittleLong(a) SwapLong(a)
#define BigFloat(a) (a)
#define LittleFloat(a) SwapFloat(a)
#else
#define BigShort(a) SwapShort(a)
#define LittleShort(a) (a)
#define BigLong(a) SwapLong(a)
#define LittleLong(a) (a)
#define BigFloat(a) SwapFoat(a)
#define LittleFloat(a) (a)
#endif

#endif
